﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using QLTT.Models;
using QLTT.Commands;
using System.Windows.Input;

namespace QLTT.ViewModels
{
    class AllClassPopupView:WorkspaceViewModel
    {
        private ObservableCollection<ClassViewModel> _lstClassViewModel;
        private icanDataContext _dataContext;
        private DelegateCommand _findCommand;
        private DelegateCommand _chooseClassCommand;
        private IQueryable<ClassViewModel> _query;
        private string _className;
        private Student _student;
        public AllClassPopupView(icanDataContext dataContext,Student oStudent)
        {
            _lstClassViewModel = new ObservableCollection<ClassViewModel>();
            _dataContext = dataContext;
            _student = oStudent;
            var queryStudentClass = _dataContext.StudentClasses.Where(studentClass => studentClass.Student == _student.ID);
            List<StudentClass> lstSClass = queryStudentClass.Select(oStudentClass => oStudentClass).ToList();
            List<long> lstClassId = new List<long>();

            //List class has full student
            List<long> lstFullClassId = new List<long>();
            List<Class> lstClassPresent = _dataContext.Classes.Where(c => c.EndDate > DateTime.Today).Select(o => o).ToList();
            foreach (Class oClass in lstClassPresent)
            {
                if (oClass.MaxStudent <= CountStudentInClass(oClass.ID))
                    lstFullClassId.Add(oClass.ID);
            }
            foreach (StudentClass oStudentClass in lstSClass)
            {
                var qClas = _dataContext.Classes.Where(o => o.ID == oStudentClass.Class);
                Class cls = qClas.Where(o => o.Fee == oStudentClass.Status).Select(o => o).FirstOrDefault();
                if (cls != null)
                    lstClassId.Add(cls.ID);
            }
            var queryClass = _dataContext.Classes.Where(oClass1 => oClass1.EndDate > DateTime.Today);
            _query = _dataContext.Classes.Where(oClass => !lstClassId.Contains(oClass.ID)).Where(oClass=>!lstFullClassId.Contains(oClass.ID)).Select(oClass => new ClassViewModel(_dataContext, oClass)); ;
            this.NumRow = _query.Count();
            this.CurPage = 1;
            this.UpdateList();

            this.Level = 0;
            this.Room = 0;
            this.Teacher = 0;
            this.ClassTime = 0;
            this.Status = Properties.Resources.Combo_AllClass_Status_InProgressOrNotYetStart;
            base.DisplayName = Properties.Resources.Base_DisplayName_AllClass;
        }
        public AllClassPopupView(icanDataContext dataContext, bool isGetAll)
        {
            _lstClassViewModel = new ObservableCollection<ClassViewModel>();
            _dataContext = dataContext;
            if (isGetAll)
            {
                //List class has full student
                List<long> lstFullClassId = new List<long>();
                List<Class> lstClassPresent = _dataContext.Classes.Where(c => c.EndDate > DateTime.Today).Select(o => o).ToList();
                foreach (Class oClass in lstClassPresent)
                {
                    if (oClass.MaxStudent <= CountStudentInClass(oClass.ID))
                        lstFullClassId.Add(oClass.ID);
                }
                _query = _dataContext.Classes.Where(oClass => oClass.EndDate>=DateTime.Today).Where(oClass=>!lstFullClassId.Contains(oClass.ID)).Select(oClass => new ClassViewModel(_dataContext, oClass));
                this.NumRow = _query.Count();
                this.CurPage = 1;
                this.UpdateList();
            }
            this.Level = 0;
            this.Room = 0;
            this.Teacher = 0;
            this.ClassTime = 0;
            this.Status = Properties.Resources.Combo_AllClass_Status_InProgressOrNotYetStart;
            base.DisplayName = Properties.Resources.Base_DisplayName_AllClass;
        }
        public string Name
        {
            get { return _className; }
            set { _className = value; }
        }
        public long Level { get; set; }
        public long Room { get; set; }
        public long Teacher { get; set; }
        public string Status { get; set; }
        public long ClassTime { get; set; }
        public DateTime StartDate { get; set; }
        public List<LevelViewModel> Levels
        {
            get
            {
                List<LevelViewModel> lstLevel = _dataContext.Levels.Select(lv => new LevelViewModel(_dataContext, lv)).ToList();
                LevelViewModel lvm = new LevelViewModel(_dataContext);
                lvm.Name = QLTT.Properties.Resources.Combo_AllClass_Level_Default;
                lstLevel.Insert(0, lvm);
                return lstLevel;
                //return new ObservableCollection<LevelViewModel>(lstLevel);
            }
        }
        public List<TeacherViewModel> Teachers
        {
            get
            {
                List<TeacherViewModel> lstTeacher = _dataContext.Teachers.Select(t => new TeacherViewModel(_dataContext, t)).ToList();
                TeacherViewModel tm = new TeacherViewModel(_dataContext);
                tm.Name = QLTT.Properties.Resources.Combo_AllClass_Teacher_Default;
                lstTeacher.Insert(0, tm);
                return lstTeacher;
            }
        }
        public List<RoomViewModel> Rooms
        {
            get
            {
                List<RoomViewModel> lstRoom = _dataContext.Rooms.Select(r => new RoomViewModel(_dataContext, r)).ToList();
                RoomViewModel rVM = new RoomViewModel(_dataContext);
                rVM.Name = QLTT.Properties.Resources.Combo_AllClass_Room_Default;
                lstRoom.Insert(0, rVM);
                return lstRoom;
            }
        }
        public List<ClassTimeViewModel> ClassTimes
        {
            get
            {
                List<ClassTimeViewModel> lstClassTime = _dataContext.ClassTimes.Select(ct => new ClassTimeViewModel(_dataContext, ct)).ToList();
                ClassTimeViewModel rVM = new ClassTimeViewModel(_dataContext);
                lstClassTime.Insert(0, rVM);
                return lstClassTime;
            }
        }
        public string[] Statuses
        {
            get
            {
                return new string[]
                {
                    Properties.Resources.Combo_AllClass_Status_InProgressOrNotYetStart,
                    Properties.Resources.Combo_AllClass_Stutus_InProgress,
                    Properties.Resources.Combo_AllClass_Status_NotYetStart,
                    Properties.Resources.Combo_AllClass_Status_Finished,
                    Properties.Resources.Combo_AllClass_Status_InProgressOrFinished,
                    Properties.Resources.Combo_AllClass_Status_Default
                    
                };
            }
        }
        public ObservableCollection<ClassViewModel> AllClasss
        {
            get { return _lstClassViewModel; }
            set {
                _lstClassViewModel = value;
                base.OnPropertyChanged("AllClasss");
            }
        }
        public ICommand FindCommand
        {
            get
            {
                if (_findCommand == null)
                {
                    _findCommand = new DelegateCommand(Find);
                }
                return _findCommand;
            }
        }
        public ICommand ChooseClassCommand
        {
            get {
                if (_chooseClassCommand == null)
                {
                    _chooseClassCommand = new DelegateCommand(ChooseClass);
                }
                return _chooseClassCommand;
            }
        }
        public void Find()
        {
            IQueryable<Class> myQuery = _dataContext.Classes;
            //List class has full student
            List<long> lstFullClassId = new List<long>();
            List<Class> lstClassPresent = _dataContext.Classes.Where(c => c.EndDate > DateTime.Today).Select(o => o).ToList();
            foreach (Class oClass in lstClassPresent)
            {
                if (oClass.MaxStudent <= CountStudentInClass(oClass.ID))
                    lstFullClassId.Add(oClass.ID);
            }
            myQuery = myQuery.Where(oClass => oClass.EndDate > DateTime.Today);
            myQuery = myQuery.Where(oClass => !lstFullClassId.Contains(oClass.ID));
            if (!string.IsNullOrEmpty(_className))
                myQuery = myQuery.Where<Class>(oClass => oClass.Name.ToLower().Contains(_className.ToLower()));
            //Add more Where Conditions here
            if (_student!=null)
            {
                var queryStudentClass = _dataContext.StudentClasses.Where(studentClass => studentClass.Student == _student.ID);
                List<long> lstClassId = queryStudentClass.Select(cStudent => cStudent.Class).ToList();
                myQuery = myQuery.Where(oClass => !lstClassId.Contains(oClass.ID));
            }
            if(this.Level > 0)
                myQuery = myQuery.Where<Class>(oClass => oClass.Level == this.Level);
            //if (this.Teacher > 0)
            //    myQuery = myQuery.Where<Class>(oClass => oClass.Teacher == this.Teacher);
            if(this.Room > 0)
                myQuery = myQuery.Where<Class>(oClass => oClass.Room == this.Room);
            if (this.ClassTime > 0)
            {
                myQuery = myQuery.Where(oClass => oClass. Schedules.Where(s => s.ClassTime == this.ClassTime).ToList().Count > 0);
            }
            if (this.Status != Properties.Resources.Combo_AllClass_Status_Default)
            {
                if(this.Status == Properties.Resources.Combo_AllClass_Status_InProgressOrNotYetStart)
                {
                    myQuery = myQuery.Where(oClass => oClass.EndDate >= DateTime.Today);
                }else if(this.Status == Properties.Resources.Combo_AllClass_Stutus_InProgress)
                {
                    myQuery = myQuery.Where(oClass => oClass.EndDate >= DateTime.Today && oClass.StartDate <= DateTime.Today);
                }
                else if (this.Status == Properties.Resources.Combo_AllClass_Status_NotYetStart)
                {
                    myQuery = myQuery.Where(oClass => oClass.StartDate > DateTime.Today);
                }
                else if (this.Status == Properties.Resources.Combo_AllClass_Status_InProgressOrFinished)
                {
                    myQuery = myQuery.Where(oClass => oClass.StartDate<DateTime.Today);
                }
                else if (this.Status == Properties.Resources.Combo_AllClass_Status_Finished)
                {
                    myQuery = myQuery.Where(oClass => oClass.EndDate < DateTime.Today);
                }
            }
            //Select
            _query = myQuery.Select(oClass => new ClassViewModel(_dataContext, oClass));
            this.NumRow = _query.Count();
            //Reset to page 0
            this.CurPage = 1;
            this.UpdateList();
        }
        private void ChooseClass()
        {
            ClassViewModel cls = _lstClassViewModel.Where(cVM => cVM.IsSelected == true).First();
            if(cls != null)
                Mediator.NotifyColleagues<ClassViewModel>(Messages.UpdateChoosingClass, cls);
            Mediator.NotifyColleagues<WorkspaceViewModel>(Messages.WorkspaceRemove, this);
        }
        [MediatorLib.MediatorMessageSink(Messages.ListClassUpdated, ParameterType = typeof(Class))]
        public void UpdateListClass(Class oClass)
        {
            this.NumRow = _query.Count();
            this.UpdateList();
        }
        private short CountStudentInClass(long clsId)
        {
            List<long> lstStudentClassId = _dataContext.StudentClasses.Where(o => o.Class == clsId).Select(o => o.ID).ToList();
            return short.Parse(lstStudentClassId.Count.ToString());
        }
        public override void UpdateList()
        {
            
            List<ClassViewModel> lstClasss = _query.Skip((this.CurPage - 1) * this.RowsPerPage).Take(this.RowsPerPage).ToList();
            AllClasss = new ObservableCollection<ClassViewModel>(lstClasss);
            base.UpdateList();
        }
    }
}
